package com.cxyd.modules.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxyd.common.constant.enums.wms.ContTypeEnum;
import com.cxyd.common.constant.enums.wms.LocateStEnum;
import com.cxyd.common.constant.enums.wms.LocateTypeEnum;
import com.cxyd.common.constant.enums.wms.StatusEnum;
import com.cxyd.common.exception.RootException;
import com.cxyd.common.page.PageData;
import com.cxyd.common.service.impl.CrudServiceImpl;
import com.cxyd.modules.api.dao.RmsNoticeDao;
import com.cxyd.modules.api.entity.RmsNoticeEntity;
import com.cxyd.modules.sys.dto.SysUserDTO;
import com.cxyd.modules.sys.service.SysUserService;
import com.cxyd.modules.wms.dao.ContainerDao;
import com.cxyd.modules.wms.dao.LocateDao;
import com.cxyd.modules.wms.dto.LocateDTO;
import com.cxyd.modules.wms.dto.po.LocatePo;
import com.cxyd.modules.wms.entity.ContainerEntity;
import com.cxyd.modules.wms.entity.LocateEntity;
import com.cxyd.modules.wms.service.LocateService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 货位信息
 *
 * @author g_Cycle gengruyi01@163.com
 * @since 1.0.0 2023-04-27
 */
@Service
public class LocateServiceImpl extends CrudServiceImpl<LocateDao, LocateEntity, LocateDTO> implements LocateService {
    private static final Logger logger = LoggerFactory.getLogger(LocateServiceImpl.class);

    private final SysUserService userService;
    private final ContainerDao containerDao;
    private final LocateDao locateDao;
    private final RmsNoticeDao rmsNoticeDao;

    public LocateServiceImpl(SysUserService userService, ContainerDao containerDao, LocateDao locateDao, RmsNoticeDao rmsNoticeDao) {
        this.userService = userService;
        this.containerDao = containerDao;
        this.locateDao = locateDao;
        this.rmsNoticeDao = rmsNoticeDao;
    }

    @Override
    public PageData<LocateDTO> page(Map<String, Object> params) {
        final IPage<LocateEntity> page = baseDao.selectPage(
                getPage(params, "locate_id", true),
                getWrapper(params)
        );
        //2.获取用户信息
        final List<SysUserDTO> userList = userService.getList();
        //3.将creator与updater的username通过id进行绑定
        page.getRecords().forEach(entity -> {
            if (entity.getCreator() != null) {
                entity.setCreatorName(userService.getUsernameById(entity.getCreator(), userList));
            }
            if (entity.getUpdater() != null) {
                entity.setUpdaterName(userService.getUsernameById(entity.getUpdater(), userList));
            }
        });

        return getPageData(page, LocateDTO.class);
    }

    @Override
    public QueryWrapper<LocateEntity> getWrapper(Map<String, Object> params) {
        String dvcNo = (String) params.get("dvcNo");
        String locateNo = (String) params.get("locateNo");
        String contNo = (String) params.get("contNo");
        String rowNum = (String) params.get("rowNum");
        String colNum = (String) params.get("colNum");
        String levelNum = (String) params.get("levelNum");
        String locateSt = (String) params.get("locateSt");

        QueryWrapper<LocateEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(dvcNo), "dvc_no", dvcNo);
        wrapper.like(StringUtils.isNotBlank(locateNo), "locate_no", locateNo);
        wrapper.like(StringUtils.isNotBlank(contNo), "cont_no", contNo);
        wrapper.eq(StringUtils.isNotBlank(rowNum), "row_num", rowNum);
        wrapper.eq(StringUtils.isNotBlank(colNum), "col_num", colNum);
        wrapper.eq(StringUtils.isNotBlank(levelNum), "level_num", levelNum);
        wrapper.eq(StringUtils.isNotBlank(locateSt), "locate_st", locateSt);

        return wrapper;
    }

    @Override
    public void batchSaveLocate(int rows, int cols, int level) {
        List<LocateEntity> locates = new ArrayList<>();
        for (int r = 1; r <= rows; r++) {
            for (int c = 1; c <= cols; c++) {
                for (int l = 1; l <= level; l++) {
                    LocateEntity entity = new LocateEntity();
                    entity.setDvcNo("YF");
                    entity.setLaneNum(1);
                    entity.setRowNum(r);
                    entity.setColNum(c);
                    entity.setLevelNum(l);
                    entity.setLocateType("HW");
                    entity.setLocateNo(String.format("HW-02K%02d%02d%02d", r, c, l));
                    locates.add(entity);
                }
            }
        }
        baseDao.batchSave(locates);
    }

    @Override
    public void locateDisabled(Map<String, Object> params) {
        Long locateId = Long.parseLong(params.get("locateId").toString());
        LocateEntity locateEntity = locateDao.selectById(locateId);
        if (ObjectUtils.isEmpty(locateEntity)) {
            throw new RootException("货位不存在");
        }
        Integer active = locateEntity.getActive();
        int activeNew;
        if (0 == active) {
            activeNew = 1;
        } else {
            activeNew = 0;
        }
        LocateEntity updateLocate = new LocateEntity();
        updateLocate.setLocateId(locateId);
        updateLocate.setActive(activeNew);
        locateDao.updateById(updateLocate);
    }

    @Override
    public void locateDisables(List<Long> ids, Integer status) {
        for (Long locateId : ids) {
            LocateEntity locateEntity = locateDao.selectById(locateId);
            if (ObjectUtils.isEmpty(locateEntity)) {
                throw new RootException("货位不存在");
            }
            //前端传入status 0就是禁用货位，传入 1就是解禁货位
            int activeNew;
            if (status == 0) {
                activeNew = 1;
            } else {
                activeNew = 0;
            }
            locateEntity.setActive(activeNew);
            locateDao.updateById(locateEntity);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public LocateEntity locatePreAllocation(String locateType,String contNo, String dvcNo, Date startDate, Long userId, String comment) {
//        if (ObjectUtils.isEmpty(containerEntity)) {
//            containerEntity = containerDao.selectOne(new QueryWrapper<ContainerEntity>().eq("cont_no", contNo));
//        }
        //货位预分配（需要根据具体的区域划分）
        LocateEntity locateEntity;
//        LocateEntity locate = locateDao.selectOne(
//                new QueryWrapper<LocateEntity>()
//                        .eq("cont_no", contNo)
//                        .eq("locate_st", LocateStEnum.PRE.getCode()));
//        if (ObjectUtils.isEmpty(locate)) {
            //查找空闲可用的货位
            List<LocateEntity> locateEntities;
            locateEntities = locateDao.selectList(
                    new QueryWrapper<LocateEntity>()
                            .eq("dvc_no", dvcNo)
                            .eq("locate_st", LocateStEnum.FREE.getCode())
                            .eq("active", StatusEnum.USABLE.getCode())
                            .like("locate_type", LocateTypeEnum.HW.getCode())
                            .orderByAsc("level_num", "col_num", "row_num"));

            if (CollectionUtils.isEmpty(locateEntities)) {
                throw new RootException("没有空闲的货位！");
            }
            locateEntity = locateEntities.get(0);
            LocatePo updateLocate = new LocatePo();
            updateLocate.setLocateId(locateEntity.getLocateId());
            updateLocate.setLocateSt(LocateStEnum.PRE.getCode());
            updateLocate.setLocateStOld(LocateStEnum.FREE.getCode());
            updateLocate.setContNo(contNo);
            updateLocate.setUpdateDate(startDate);
            updateLocate.setUpdater(userId);
            updateLocate.setComments(comment);
            int locateUpdateNum = locateDao.occupy(updateLocate);
            if (locateUpdateNum <= 0) {
                throw new RootException("货位预占用失败！");
            }
//            if (!ObjectUtils.isEmpty(rmsNoticeEntity)) {
//                rmsNoticeDao.deleteById(rmsNoticeEntity.getId());
//            }
//        } else {
//            locateEntity = locate;
//        }
        return locateEntity;
    }

    @Override
    public List<LocateEntity> findByParams(Map<String, Object> map) {
        String rowNum = (String) map.get("row_num");
        String colNum = (String) map.get("col_num");
        String levelNum = (String) map.get("level_num");
        String dvcNo = (String) map.get("dvc_no");
        String locate_type = (String) map.get("locate_type");

        QueryWrapper<LocateEntity> wrapper = new QueryWrapper<>();
        wrapper.eq(StringUtils.isNotBlank(rowNum), "row_num", rowNum);
        wrapper.eq(StringUtils.isNotBlank(colNum), "col_num", colNum);
        wrapper.eq(StringUtils.isNotBlank(levelNum), "level_num", levelNum);
        wrapper.eq(StringUtils.isNotBlank(dvcNo), "dvc_no", dvcNo);
        wrapper.eq(StringUtils.isNotBlank(locate_type), "locate_type", locate_type);
        return baseDao.selectList(wrapper);
    }

}